Вам нужно защитить данные клиентов страховой компании «Хоть потоп». Разработайте такой метод преобразования данных, чтобы по ним было сложно восстановить персональную информацию. Обоснуйте корректность его работы.
Нужно защитить данные, чтобы при преобразовании качество моделей машинного обучения не ухудшилось. Подбирать наилучшую модель не требуется.
import pandas as pd
import numpy as np
import seaborn as sns
import warnings
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score
warnings.filterwarnings('ignore')
try:
data = pd.read_csv('/datasets/insurance.csv')
except:
data = pd.read_csv('F:/insurance.csv')
display(data.head(), data.shape,)
Пол | Возраст | Зарплата | Члены семьи | Страховые выплаты | |
---|---|---|---|---|---|
0 | 1 | 41.0 | 49600.0 | 1 | 0 |
1 | 0 | 46.0 | 38000.0 | 1 | 1 |
2 | 0 | 29.0 | 21000.0 | 0 | 0 |
3 | 0 | 21.0 | 41700.0 | 2 | 0 |
4 | 1 | 28.0 | 26100.0 | 0 | 0 |
(5000, 5)
data.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5000 entries, 0 to 4999 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Пол 5000 non-null int64 1 Возраст 5000 non-null float64 2 Зарплата 5000 non-null float64 3 Члены семьи 5000 non-null int64 4 Страховые выплаты 5000 non-null int64 dtypes: float64(2), int64(3) memory usage: 195.4 KB
data.describe()
Пол | Возраст | Зарплата | Члены семьи | Страховые выплаты | |
---|---|---|---|---|---|
count | 5000.000000 | 5000.000000 | 5000.000000 | 5000.000000 | 5000.000000 |
mean | 0.499000 | 30.952800 | 39916.360000 | 1.194200 | 0.148000 |
std | 0.500049 | 8.440807 | 9900.083569 | 1.091387 | 0.463183 |
min | 0.000000 | 18.000000 | 5300.000000 | 0.000000 | 0.000000 |
25% | 0.000000 | 24.000000 | 33300.000000 | 0.000000 | 0.000000 |
50% | 0.000000 | 30.000000 | 40200.000000 | 1.000000 | 0.000000 |
75% | 1.000000 | 37.000000 | 46600.000000 | 2.000000 | 0.000000 |
max | 1.000000 | 65.000000 | 79000.000000 | 6.000000 | 5.000000 |
display(data.corr(), sns.heatmap(data.corr(), annot=True))
Пол | Возраст | Зарплата | Члены семьи | Страховые выплаты | |
---|---|---|---|---|---|
Пол | 1.000000 | 0.002074 | 0.014910 | -0.008991 | 0.010140 |
Возраст | 0.002074 | 1.000000 | -0.019093 | -0.006692 | 0.651030 |
Зарплата | 0.014910 | -0.019093 | 1.000000 | -0.030296 | -0.014963 |
Члены семьи | -0.008991 | -0.006692 | -0.030296 | 1.000000 | -0.036290 |
Страховые выплаты | 0.010140 | 0.651030 | -0.014963 | -0.036290 | 1.000000 |
<AxesSubplot:>
data.isna().sum()
Пол 0 Возраст 0 Зарплата 0 Члены семьи 0 Страховые выплаты 0 dtype: int64
data.duplicated().sum()
153
Комментарий:
Данные успешно загружены и имеют подходящий тип данных. Для удобства переведем возраст и зарплату в целочисленный формат, так как дробная часть не имеет значения в данном контексте. В таблице отсутствуют лишние столбцы и пропущенные значения. Дубликаты будут удалены, их происхождение неясно, однако они не являются необходимыми для обучения модели. Проверка основных статистических показателей не выявила явных выбросов. Наблюдается высокая корреляция между возрастом и зарплатой (коэффициент корреляции 0.65).
data = data.drop_duplicates()
data['Возраст'] = data['Возраст'].astype("int64")
data['Зарплата'] = data['Зарплата'].astype("int64")
В этом задании вы можете записывать формулы в Jupyter Notebook.
Чтобы записать формулу внутри текста, окружите её символами доллара \$; если снаружи — двойными символами \$\$. Эти формулы записываются на языке вёрстки LaTeX.
Для примера мы записали формулы линейной регрессии. Можете их скопировать и отредактировать, чтобы решить задачу.
Работать в LaTeX необязательно.
Обозначения:
$X$ — матрица признаков (нулевой столбец состоит из единиц)
$y$ — вектор целевого признака
$P$ — матрица, на которую умножаются признаки
$w$ — вектор весов линейной регрессии (нулевой элемент равен сдвигу)
Предсказания:
$$ a = Xw $$Задача обучения:
$$ w = \arg\min_w MSE(Xw, y) $$Формула обучения:
$$ w = (X^T X)^{-1} X^T y $$Ответ: R2 не изменится
Обоснование:
Умножение матрицы на матрицу возможно, если ширина первой матрицы $А(𝑚×𝑛)$ равна высоте второй матрицы $P (𝑛×r)$. Тогда размер произведения этих матриц будет $m×r$. Размерность n «cхлопывается».
При умножении признаков выборки $A$ размерностью $(3750,4)$ на обратимую произвольную матрицу $P$ размерностью $(4,4)$, результатом получаем новый (изменённый) набор данных скалярных произведений $M$ размернотью $(3750, 4)$
Формула выглядит следующим образом:
$$
Mij = (Ai,Bj)
$$
В каждую новую ячейку записывается результат сложения произведений строки $i$ на столбец $j$. Так например в первой ячейке новой таблицы будет записан результат по этой формуле:
$$
M_{11}=A_{11}×P_{11} + A_{12}×P_{21} + A_{13}×P_{31} + A_{14}×P_{41}
$$
Далее вычисляется важный параметр - вектор $w$ по формуле: $$ w = (X^T X)^{-1} X^T y $$
В Линейной регрессии
предсказания вычисляются по формуле:
, где $w0$ - значение нулевого аргумента вектора $w$, которое предствляет собой величину сдвига модели, при подборе которого можно достигать более низкого значения среднеквадратичного отклонения $MSE$
Рассмотрим упрощённую запись формулы предсказания Линейной регрессии
$
a = X_i w
$, где $X_i$ - новые строки признаков
Подставим вместо параметра $w$, формулу её вычисления:
$$
a = X_i w = X_i (X^T X)^{-1} X^T y
$$
Упроситим формулу используя принцип ассоциативности ($A(BC) = (AB)C$) и то, что транспонированное произведение матриц равно произведению транспонированных матриц взятых в обратном порядке ($(AB)^T = B^T A^T$):
$$ a = X_i (X^T X)^{-1} X^T y = X_iX^{-1}(X^T)^{-1}X^T y = X_iX^{-1}y $$Домножим наши признаки на случайную матрицу $P$, в которой число строк равно чилу столбцов $X$ и $P$ - обратима, то есть из матрицы $P$ можно получить матрицу $P^{-1}$, при этом $PP^{-1} = E$, где $E$ - единичная матрица
Если обучить нашу модель на новых (изменённых) признаках, то модель найдёт новые коэффициенты $w'$
$$ w' = ((XP)^T(XP))^{-1}(XP)^Ty $$Подставим их в формулу предсказания и упростим выражение
$$ a'= X_iPw' = X_iP((XP)^T(XP))^{-1}(XP)^Ty = X_iP(XP)^{-1}((XP)^T)^{-1}(XP)^Ty = X_iX^{-1}y $$Таким образом мы пришли к заключению, о том что результат предсказания не изменится не смотря на измениения признаков, т.к. исходя из результатов наших преобразований очевидно, что $a$ = $a'$
Алгоритм
Мы создаем квадратную матрицу, размер которой соответствует количеству признаков, и заполняем ее случайными числами. Затем мы проверяем, является ли эта матрица обратимой, то есть имеет обратную матрицу. Если матрица обратима, мы умножаем наши признаки на эту матрицу.
Важно отметить, что требуется, чтобы матрица была обратимой, чтобы мы могли успешно восстановить исходные данные. В противном случае, если матрица необратима, мы не сможем расшифровать наши данные.
Обоснование
Мы можем ожидать, что качество линейной регрессии будет одинаковым до и после преобразования данных. Преобразование данных не влияет на способность модели предсказывать целевой признак. Однако, эти действия имеют важное значение для защиты персональных данных клиентов. В случае возможной утечки данных, преобразование матрицы признаков обеспечивает дополнительную безопасность, поскольку злоумышленникам эти данные будут бесполезны.
features = data.drop(["Страховые выплаты"], axis=1)
target = data["Страховые выплаты"]
features.shape, target.shape
((4847, 4), (4847,))
matrix = np.random.randint(100,size = (4, 4))
matrix
array([[61, 78, 66, 57], [96, 25, 62, 81], [33, 9, 67, 57], [22, 51, 88, 30]])
matrix_inv = np.linalg.inv(matrix)
matrix_inv
array([[-0.01671234, 0.02824602, -0.03262188, 0.01747076], [ 0.02102849, -0.01135376, -0.00134096, -0.00675118], [-0.0169794 , 0.00747934, -0.0059387 , 0.02335016], [ 0.02631352, -0.02335177, 0.04362251, -0.03649535]])
model = LinearRegression(normalize=True).fit(features, target)
predictions = model.predict(features)
r2_score_value = r2_score(target, predictions)
print(f"R2_score: {r2_score_value:.13f}")
R2_score: 0.4302010046633
features_matrix = features.dot(matrix)
model = LinearRegression(normalize = True).fit(features_matrix, target)
predictions = model.predict(features_matrix)
r2_score_value = r2_score(target, predictions)
print(f"R2_score: {r2_score_value:.13f}")
R2_score: 0.4302010046633
Оставлю хороший учебник по ML:
Немного новостей с мира DL(вдруг заинтересует):
Вот тут проходят всякие соревнования, можешь себя попробовать:
Если хочешь подтянуть Математику для DS то, например:
Coursera, к сожалению уходит из России...но все равно расскажу лайфхак как там получить курс бесплатно. https://techrocks.ru/2021/07/31/coursera-edx-udacity-free-learning-resources/#:~:text=%D0%9D%D0%BE%20%D0%B5%D1%81%D1%82%D1%8C%20%D0%B5%D1%89%D0%B5%20%D0%BE%D0%B4%D0%BD%D0%B0%20%D0%BE%D0%BF%D1%86%D0%B8%D1%8F,%D1%80%D0%B5%D1%88%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B2%20%D1%82%D0%B5%D1%87%D0%B5%D0%BD%D0%B8%D0%B5%20%D0%B4%D0%B2%D1%83%D1%85%20%D0%BD%D0%B5%D0%B4%D0%B5%D0%BB%D1%8C.
Возможно, что нить пригодится:
Курс от МФТИ математика для DS:
Тут много соревнований/лекций:
stepic NLP/CV:
Еще есть от ВШЭ:
Поставьте 'x' в выполненных пунктах. Далее нажмите Shift+Enter.